package com.zhaotianhao.util;

import com.alibaba.fastjson.JSON;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.SearchResultMapper;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.aggregation.impl.AggregatedPageImpl;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;


/**
 * @author Z-7
 */
public class HighLightResultMapper implements SearchResultMapper {
    @Override
    public <T> AggregatedPage<T> mapResults(SearchResponse searchResponse, Class<T> clazz, Pageable pageable) {
        //获取搜索后数据总条数
        long totalHits = searchResponse.getHits().getTotalHits();
        List<T> list = new ArrayList<>();
        //获取es搜索的数据集合对象
        SearchHits hits = searchResponse.getHits();
        if (hits.getHits().length> 0) {
            //遍历数据集合
            for (SearchHit searchHit : hits) {
                //获取要高亮字段
                Map<String, HighlightField> highlightFields = searchHit.getHighlightFields();
                //{"id":"4","title":"出塞","content":"秦时明月汉时关，万里长征人未还。但使龙城飞将在，不教胡马度阴山。"
                //把json串转为目标对象
                T item = JSON.parseObject(searchHit.getSourceAsString(), clazz);
                //获取目标对象的所有属性
                Field[] fields = clazz.getDeclaredFields();
                //遍历属性
                for (Field field : fields) {
                    //设置私有属性可以访问
                    field.setAccessible(true);
                    //如果高亮的字段和要封装的对象的名字一致则值要重新封装
                    if (highlightFields.containsKey(field.getName())) {
                        try {
                            field.set(item, highlightFields.get(field.getName()).fragments()[0].toString());
                        } catch (IllegalAccessException e) {
                            e.printStackTrace();
                        }
                    }
                }
                list.add(item);
            }
        }
        return new AggregatedPageImpl<>(list, pageable, totalHits);

    }
}
